﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Cyss.Core
{
    /// <summary>
    /// 日志服务
    /// </summary>
    public class LogSevice
    {

        static LogSevice()
        {
            LogQueue = new ConcurrentQueue<LogModel>();
            _timer = new System.Threading.Timer(WriteLog, 0, Interval, Interval);
        }
        /// <summary>
        /// 日志队列
        /// </summary>
        private static ConcurrentQueue<LogModel> LogQueue;

        /// <summary>
        /// 
        /// </summary>
        private static System.Threading.Timer _timer;

        /// <summary>
        /// 一次做大提取数量
        /// </summary>
        private static int MaxCount = 100;

        /// <summary>
        /// 间隔微秒
        /// </summary>
        private static int Interval = 1000;

        /// <summary>
        /// 写入日志
        /// </summary>
        /// <param name="Message"></param>
        /// <param name="FielName"></param>
        /// <param name="IsHourSplit"></param>
        public static void Write(string Message, string FielName, bool IsHourSplit = false)
        {
            try
            {
                LogModel logModel = new LogModel();
                logModel.Content = Message;
                logModel.FileName = FielName;
                logModel.IsHourSplit = IsHourSplit;
                LogQueue.Enqueue(logModel);
            }
            catch (Exception ex)
            {


            }
        }

        /// <summary>
        /// 
        /// </summary>
        private static void WriteLog(object state)
        {
            _timer.Change(-1, -1);
            try
            {
                int count = 0;
                List<LogModel> list = new List<LogModel>();
                while (true)
                {
                    count++;
                    LogModel logModel = null;
                    var isSuccess = LogQueue.TryDequeue(out logModel);
                    if (logModel != null)
                    {
                        list.Add(logModel);
                    }
                    if (isSuccess == false)
                    {
                        break;
                    }
                    if (count > MaxCount)
                    {
                        break;
                    }
                }

                foreach (var item in list.GroupBy(x => new { x.FileName, x.IsHourSplit }))
                {
                    var Message = string.Join(Environment.NewLine, item.Select(x => x.Content));
                    WriteText(Message, item.Key.FileName, item.Key.IsHourSplit);
                }
                list = null;

                if (DateTime.Now.Hour == 14 && DateTime.Now.Minute == 15)
                {
                    ClearLog();
                }
            }
            catch (Exception ex)
            {

            }
            _timer.Change(Interval, Interval);
        }

        /// <summary>
        /// 清理日志
        /// </summary>
        private static void ClearLog()
        {
            try
            {
                var systemConfig = IOCEngine.Resolve<SystemConfig>();
                string path = AppDomain.CurrentDomain.BaseDirectory + @"\Log\";
                DirectoryInfo directory = new DirectoryInfo(path);
                foreach (var dir in directory.GetDirectories())
                {
                    if (DateTime.Parse(dir.Name) <= DateTime.Now.AddDays(-systemConfig.LogDays))
                    {
                        dir.Delete(true);
                    }
                }
            }
            catch (Exception ex)
            {
                LogSevice.Write(ex.ToString(), "ClearLog");
            }

        }

        private static void WriteText(string Message, string FileName, bool IsHourSplit = false)
        {
            try
            {
                DateTime time = DateTime.UtcNow.AddHours(8);//所有的日志以北京时间记录
                string path = AppDomain.CurrentDomain.BaseDirectory + @"\Log\";
                if (!Directory.Exists(path))
                    Directory.CreateDirectory(path);

                path = path + time.ToString("yyyy-MM-dd");
                if (!Directory.Exists(path))
                    Directory.CreateDirectory(path);

                if (string.IsNullOrWhiteSpace(FileName))
                {
                    FileName = "log";
                }

                if (IsHourSplit)
                {
                    FileName = FileName + "-" + time.Hour.ToString();
                }

                string fileFullPath = path + $@"\{FileName}.txt";

                StreamWriter sw;
                if (!File.Exists(fileFullPath))
                {
                    sw = File.CreateText(fileFullPath);
                }
                else
                {
                    sw = File.AppendText(fileFullPath);
                }
                sw.WriteLine(Message);
                sw.Close();
                sw = null;
            }
            catch (Exception ex)
            {

            }

        }

    }

    /// <summary>
    /// 
    /// </summary>
    internal class LogModel
    {
        /// <summary>
        /// 日志内容
        /// </summary>
        public string Content { set; get; }

        /// <summary>
        /// 文件名称
        /// </summary>
        public string FileName { set; get; }

        /// <summary>
        /// 是否按小时分开
        /// </summary>
        public bool IsHourSplit { set; get; }
    }
}
